// Copyright (C) 2005 Taylor L. Riché <riche@cs.utexas.edu>
//  
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software 
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// 	$Id: AGFactoryPrinter.java 69 2005-08-02 15:46:18Z richetl $	
//

import java.io.*;

class AGFactoryPrinter
{
    public void print(String appName, PpaDecls d, PpaWirings w) {
	String filename = "llt_" + appName + ".hh";
	FileOutputStream out = null;
	PrintStream file = null;
	try {
	    out = new FileOutputStream(filename);
	    file = new PrintStream(out);
	}
	catch (FileNotFoundException e) {
	    System.err.println("Specified file " + filename + " does not exist.");
	    System.exit(1);
	}
	
	// Print guards
	file.println("#ifndef LLT_" + appName.toUpperCase() + "_H");
	file.println("#define LLT_" + appName.toUpperCase() + "_H");
	file.println();

	// Automatic includes
	file.println("#include <lee/ApplicationGraph.hh>");
	file.println("#include <lee/NetInterface.hh>");
	file.println();

	// Include generated ppf header files
	d.printIncludes(file);

	// Print out prototype of "C" factory function
	file.println("extern \"C\" {");
	file.println("lee::ApplicationGraph * getAG(int i);");
	file.println("}");
	file.println();

	// Print namespace
	file.println("namespace " + appName + " {");

	// Start class definition
	file.println("class " + appName + "_AG : public lee::ApplicationGraph");
	file.println("{");
	file.println("\tvirtual void init();");
	file.println("public:");
	file.println("\t" + appName + "_AG(int i) : lee::ApplicationGraph(i) {init();}");
	file.println("\tvirtual ~" + appName + "_AG() {}");
	file.println("};");
	file.println();

	// Close out namespace
	file.println("}");
	file.println();

	// Close out file
	file.println("#endif");
	file.println();

	// Now that we are done with the header, print out the body
	filename = "llt_" + appName + ".cc";
	try {
	    out = new FileOutputStream(filename);
	    file = new PrintStream(out);
	}
	catch (FileNotFoundException e) {
	    System.err.println("Specified file " + filename + " does not exist.");
	    System.exit(1);
	}
	
	file.println("#include \"llt_" + appName + ".hh\"");
	file.println();

	file.println("using namespace " + appName + ";");

	// Define factory function
	file.println("extern \"C\" {");
	file.println("lee::ApplicationGraph * getAG(int i)");
	file.println("{");
	file.println("\treturn new " + appName + "_AG(i);");
	file.println("}");
	file.println("}");
	file.println();

	// Override standard init method
	file.println("void");
	file.println(appName + "_AG::init()");
	file.println("{");

	// Properly setup the packet devices
	file.println("\tcreateNetInterfaceEntry();");

	// Create the declared ppfs

	d.print(file);

	// Create the wirings

	w.setEnv(d.getEnv());
	w.print(file);

	file.println("\treturn;");
	file.println("}");
	file.println();
    }
}

